/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package argtrust.argsys;

import argtrust.trustnet.Agent;
import argtrust.util.Pair;

/**
 *
 * @author Yuqing Tang
 */
public class LabelPreferredMembershipSemantics extends LabelSemantics {

    public LabelPreferredMembershipSemantics(ArgumentationSystem arg_sys,
            IBeliefArgumentSemantics arg_belief) {
        super(arg_sys, arg_belief);
    }

    /**
     * TODO: Need to carefully think through the algorithm.
     * @param agent
     * @param argument
     * @return
     */
    public ArgumentStatus getStatus(Agent agent, Argument argument) {
        LabelStatus res = computeStatus_(agent, argument, 0);
        if (!res.isFinal()) {
            int old_status = res.getStatus();
            res.setStatus(LabelStatus.IN);
            res.unsetFinal();
            if (tryLabel_(agent, argument)) {
                return res;
            } else {
                res.setStatus(old_status);
            }
        }
        return res;
    }

    protected boolean tryLabel_(Agent agent, Argument argument) {
        Pair<Agent, Argument> key = new Pair<Agent, Argument>(agent, argument);

        LabelStatus status = mArgumentStatusTable.get(key);
        if (status != null) {
            ArguingNode arg_node = mArgSys.getArguingNode(argument);
            assert (arg_node != null);
//            boolean has_in_child = false;
            for (ArguingLink arg_link : arg_node.getArguingLinkList()) {
                if (!isEffective(agent, arg_link.getDefeat())) {
                    continue;
                }
                ArguingNode next_node = arg_link.getDefeaterNode();
                Argument defeater = next_node.getArgument();
                LabelStatus defeater_status = mArgumentStatusTable.get(
                        new Pair<Agent, Argument>(agent, defeater));
                if (status.isIn()) {
                    if (defeater_status.isIn()) {
                        return false;
                    } else if (defeater_status.isOut()) {
                        continue;
                    } else if (defeater_status.isUndec()) {
                        int old_status = defeater_status.getStatus();
                        defeater_status.setStatus(LabelStatus.OUT);
                        defeater_status.unsetFinal();
                        if (tryLabel_(agent, defeater) == false) {
                            defeater_status.setStatus(old_status);
                            return false;
                        }


                    }
                } else if (status.isOut()) {
                    if (defeater_status.isIn()) {
                        return true;
                    } else if (defeater_status.isOut()) {
                        continue;
                    } else if (defeater_status.isUndec()) {
                        int old_status = defeater_status.getStatus();
                        defeater_status.setStatus(LabelStatus.IN);
                        defeater_status.unsetFinal();
                        if (tryLabel_(agent, defeater) == true) {
                            return true;
                        }
                        defeater_status.setStatus(old_status);
                        defeater_status.setFinal();

                    }
                }
                assert !status.isUndec();
            }


        }
        return false;
    }
}
